package com.graden.background.service.sysrole.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.graden.background.service.sysuser.ISysUserService;
import com.graden.background.common.conf.aop.sso.AopResourceUserInfoBean;
import com.graden.background.common.utils.exception.ExceptionManager;
import com.graden.background.controller.sysrole.vo.RoleActivateVO;
import com.graden.background.controller.sysrole.vo.RoleAddVO;
import com.graden.background.controller.sysrole.vo.RoleSelectVO;
import com.graden.background.controller.sysrole.vo.RoleUpdateVO;
import com.graden.background.repository.sysrole.SysRoleMapper;
import com.graden.background.repository.sysrole.entity.SysRole;
import com.graden.background.repository.sysrole.entity.SysRoleDTO;
import com.graden.background.repository.sysrolefunction.entity.SysRoleFunction;
import com.graden.background.repository.sysrolemenu.entity.SysRoleMenu;
import com.graden.background.repository.sysroleuser.entity.SysRoleUser;
import com.graden.background.repository.sysuser.entity.SysUser;
import com.graden.background.service.sysrole.ISysRoleService;
import com.graden.background.service.sysrolefunction.ISysRoleFunctionService;
import com.graden.background.service.sysrolemenu.ISysRoleMenuService;
import com.graden.background.service.sysroleuser.ISysRoleUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 系统角色服务实现类
 * </p>
 *
 * @author zjf
 * @since 2019-03-21
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {

	@Resource
	SysRoleMapper sysRoleMapper;

	@Resource
	ISysRoleUserService iSysRoleUserService;

	@Resource
	ISysRoleFunctionService iSysRoleFunctionService;

	@Resource
	ISysRoleMenuService iSysRoleMenuService;

	@Resource
	ApplicationContext applicationContext;

	@Resource
	ExceptionManager exceptionManager;

	@Resource
	ISysUserService iSysUserService;

	/**
	 * 查询角色列表（包含高级查询）
	 */
	@Override
	public PageInfo getAllByPage(int pageNo, int size, RoleSelectVO roleSelectVO) {
		PageHelper.startPage(pageNo, size);

		QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();

		if(StringUtils.isNotEmpty(roleSelectVO.getName())){
			queryWrapper.like("name",roleSelectVO.getName());
		}

		return new PageInfo<>(sysRoleMapper.selectList(queryWrapper));
	}

	/**
	 * 查询角色列表（包含高级查询）
	 */
	@Override
	public List<SysRole> getAll() {
		return this.list();
	}

	@Override
	public SysRoleDTO getInfo(Integer id) {

		QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("id", id);
		SysRole sysRole = this.getOne(queryWrapper);

		if (sysRole == null) {
			throw exceptionManager.create("ROLE_0002");
		}

		SysRoleDTO sysRoleDTO = new SysRoleDTO();
		BeanUtils.copyProperties(sysRole, sysRoleDTO);

		//根据role_id获取菜单权限
		QueryWrapper<SysRoleMenu> queryRoleMenuWrapper = new QueryWrapper<>();
		queryRoleMenuWrapper.eq("role_id", id);
		List<SysRoleMenu> sysRoleMenus = iSysRoleMenuService.list(queryRoleMenuWrapper);
		Integer[] menus = new Integer[sysRoleMenus.size()];
		for (int i = 0; i < sysRoleMenus.size(); i++) {
			menus[i] = sysRoleMenus.get(i).getMenuId();
		}
		sysRoleDTO.setMenus(menus);

		//根据role_id获取功能权限
		QueryWrapper<SysRoleFunction> queryRoleFunctionWrapper = new QueryWrapper<>();
		queryRoleFunctionWrapper.eq("role_id", id);
		List<SysRoleFunction> sysRoleFunctions = iSysRoleFunctionService.list(queryRoleFunctionWrapper);
		Integer[] functions = new Integer[sysRoleFunctions.size()];
		for (int i = 0; i < sysRoleFunctions.size(); i++) {
			functions[i] = sysRoleFunctions.get(i).getFunctionId();
		}
		sysRoleDTO.setFunctions(functions);


		return sysRoleDTO;
	}

	/**
	 * 添加角色
	 */
	@Transactional
	@Override
	public void addRole(RoleAddVO roleAddVO) {

		SysRole sysRole = new SysRole();
		BeanUtils.copyProperties(roleAddVO, sysRole);

		sysRole.setId(0);
		sysRole.setCreateTime(LocalDateTime.now());
		sysRole.setUpdateTime(LocalDateTime.now());

		//查看是否存在角色
		QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("name", sysRole.getName());

		SysRole resultSysRole = this.getOne(queryWrapper);
		if (resultSysRole != null) {
			throw exceptionManager.create("ROLE_0003");
		}

		sysRoleMapper.insertAndGetId(sysRole);

		if (roleAddVO.getMenus() != null) {
			iSysRoleMenuService.saveMenu(sysRole.getId(), roleAddVO.getMenus());
		}

		if (roleAddVO.getFunctions() != null) {
			iSysRoleFunctionService.saveFunction(sysRole.getId(), roleAddVO.getFunctions());
		}

	}

	/**
	 * 修改角色信息
	 */
	@Transactional
	@Override
	public void updateRole(RoleUpdateVO roleUpdateVO) {

		SysRole sysRole = new SysRole();
		BeanUtils.copyProperties(roleUpdateVO, sysRole);

		sysRole.setUpdateTime(LocalDateTime.now());

		//查看是否存在角色
		SysRole resultSysRole = sysRoleMapper.selectById(sysRole.getId());

		if (resultSysRole == null) {
			throw exceptionManager.create("ROLE_0002");
		}

		sysRoleMapper.updateById(sysRole);

		//删除该角色下所有菜单权限
		QueryWrapper<SysRoleMenu> menuWrapper = new QueryWrapper<>();
		menuWrapper.eq("role_id", sysRole.getId());
		iSysRoleMenuService.remove(menuWrapper);

		//删除该角色下所有功能权限
		QueryWrapper<SysRoleFunction> functionWrapper = new QueryWrapper<>();
		functionWrapper.eq("role_id", sysRole.getId());
		iSysRoleFunctionService.remove(functionWrapper);

		if (roleUpdateVO.getMenus() != null) {
			iSysRoleMenuService.saveMenu(sysRole.getId(), roleUpdateVO.getMenus());
		}

		if (roleUpdateVO.getFunctions() != null) {
			iSysRoleFunctionService.saveFunction(sysRole.getId(), roleUpdateVO.getFunctions());
		}

		//当修改的角色与当前登录人的角色一样的时候重新注入
		AopResourceUserInfoBean aopResourceUserInfoBean = applicationContext.getBean(AopResourceUserInfoBean.class);
		if(aopResourceUserInfoBean.getSysRoleList() !=null) {
			for (SysRole itemRole : aopResourceUserInfoBean.getSysRoleList()) {
				if (sysRole.getId() == itemRole.getId()) {
					SysUser sysUser = new SysUser();
					BeanUtils.copyProperties(aopResourceUserInfoBean, sysUser);
					iSysUserService.injectUserRequestScope(sysUser);
					break;
				}
			}
		}


	}

	/**
	 * 角色状态（可用/不可用）设置
	 */
	@Transactional
	@Override
	public void activateRole(RoleActivateVO roleActivateVO) {
		SysRole sysRole = new SysRole();
		BeanUtils.copyProperties(roleActivateVO, sysRole);
		sysRole.setUpdateTime(LocalDateTime.now());

		sysRoleMapper.updateById(sysRole);

		//把角色用户的关联表也设置
		UpdateWrapper roleUserWrapper = new UpdateWrapper();
		roleUserWrapper.eq("role_id", sysRole.getId());
		roleUserWrapper.set("status", roleActivateVO.getStatus());
		iSysRoleUserService.update(roleUserWrapper);

		UpdateWrapper roleFunctionWrapper = new UpdateWrapper();
		roleFunctionWrapper.eq("role_id", sysRole.getId());
		roleFunctionWrapper.set("status", roleActivateVO.getStatus());
		iSysRoleFunctionService.update(roleFunctionWrapper);

		UpdateWrapper roleMenuWrapper = new UpdateWrapper();
		roleMenuWrapper.eq("role_id", sysRole.getId());
		roleMenuWrapper.set("status", roleActivateVO.getStatus());
		iSysRoleMenuService.update(roleFunctionWrapper);

	}

	@Transactional
	@Override
	public void deleteRole(int id) {

		sysRoleMapper.deleteById(id);

		//删除与角色用户关联表的数据
		QueryWrapper<SysRoleUser> querySysRoleUserWrapper = new QueryWrapper<>();
		querySysRoleUserWrapper.eq("role_id",id);
		iSysRoleUserService.remove(querySysRoleUserWrapper);

		//删除与角色菜单关联表的数据
		QueryWrapper<SysRoleMenu> querySysRoleMenuWrapper = new QueryWrapper<>();
		querySysRoleMenuWrapper.eq("role_id",id);
		iSysRoleMenuService.remove(querySysRoleMenuWrapper);

		//删除与角色功能关联表的数据
		QueryWrapper<SysRoleFunction> querySysRoleFunctionWrapper = new QueryWrapper<>();
		querySysRoleFunctionWrapper.eq("role_id",id);
		iSysRoleFunctionService.remove(querySysRoleFunctionWrapper);

	}
}
